package com.jnxx.okr.service.impl;

import com.jnxx.basic.service.impl.BaseServiceImpl;
import com.jnxx.basic.util.GetStaffRequestUtil;
import com.jnxx.okr.domain.Alignment;
import com.jnxx.okr.domain.Okr;
import com.jnxx.okr.domain.Okrandstaff;
import com.jnxx.okr.domain.Renew;
import com.jnxx.okr.mapper.AlignmentMapper;
import com.jnxx.okr.mapper.OkrMapper;
import com.jnxx.okr.mapper.OkrandstaffMapper;
import com.jnxx.okr.mapper.RenewMapper;
import com.jnxx.okr.service.IOkrService;
import com.jnxx.task.domain.Cycle;
import com.jnxx.task.domain.OkrStaff;
import com.jnxx.task.domain.Task;
import com.jnxx.task.mapper.CycleMapper;
import com.jnxx.task.mapper.OkrStaffMapper;
import com.jnxx.task.mapper.TaskMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 业务实现类：
 */
@Slf4j
@Service
public class OkrServiceImpl extends BaseServiceImpl<Okr> implements IOkrService {

//    @Autowired
//    private KrMapper krMapper;
//
    @Autowired
    private OkrandstaffMapper okrandstaffMapper;

    @Autowired
    private OkrMapper okrMapper;

    @Autowired
    private RenewMapper renewMapper;
    @Autowired
    private OkrStaffMapper staffMapper;
    @Autowired
    private AlignmentMapper alignmentMapper;

    @Autowired
    private TaskMapper taskMapper;

    @Autowired
    private CycleMapper cycleMapper;

    @Autowired
    private AlignmentServiceImpl alignmentService;


    @Override
    public void update(Okr okr) {
        OkrStaff login = GetStaffRequestUtil.getStaff();
        log.info("{}跟新了名为：{}的okr",login.getName(), okr.getName());
        super.update(okr);
        Long id = okr.getId();
        List<OkrStaff> staffList = okr.getStaffList();
        // 先删除关系
        okrandstaffMapper.delByOkrId(id);
        // 再添加
        for (OkrStaff staff : staffList) {
            Okrandstaff okrandstaff = new Okrandstaff();
            okrandstaff.setOkrId(Math.toIntExact(id));
            okrandstaff.setStaffId(Math.toIntExact(staff.getId()));
            okrandstaff.setCycleId(Math.toIntExact(okr.getCycleId()));
            okrandstaff.setCreatId(Math.toIntExact(login.getId()));
            okrandstaffMapper.add(okrandstaff);
        }
        // 修改完成的kr
        List<Okr> krList = okr.getSubOkrList();
        if (krList.size() > 0){
            // 修改和添加kr
            for (Okr kr : krList) {
                kr.setParentId(id);
                if (kr.getProgress() == null){
                    kr.setProgress(0);
                }
                kr.setLeader(okr.getLeader());
                kr.setType(okr.getType());
                kr.setCycleId(okr.getCycleId());
                if( kr.getId()!=null){
                    okrMapper.update(kr);
                }else{
                    okrMapper.add(kr);
                }
            }
        }
        // 以前的kr
        List<Okr> oldSubOkrList = okrMapper.findByParentId(id);
        // 新的有，以前的也有，找出删除了的，删掉
        if (krList.size() > 0 && oldSubOkrList.size() > 0){
            // 找到删除的okr
            List<Long> deletedKrIds = oldSubOkrList.stream()
                    .filter(oldKr -> krList.stream().noneMatch(kr -> kr.getId().equals(oldKr.getId())))
                    .map(Okr::getId)
                    .collect(Collectors.toList());
            // 如果存在该删除的，就删除
            if (deletedKrIds.size() >0){
                okrMapper.batchDel(deletedKrIds);
                renewMapper.batchDelByOkrId(deletedKrIds);
            }
        } else if (oldSubOkrList.size() == 0 && krList.size() != 0){
            // 没有新的，有旧的，说明删完了
            List<Long> oldKrIds = krList.stream()
                    .map(Okr::getId)
                    .collect(Collectors.toList());
            okrMapper.batchDel(oldKrIds);
        }

        // 关于对齐目标的修改
        List<Okr> alignmentForOkrList;
        alignmentForOkrList = okr.getAlignmentForOkrList();
        // 从数据库删除原来的
//        alignmentMapper.delBySourceId(okr.getId());

        // 说明有变动
//        if(alignmentForOkrList != null ){
//           // 在重新添加
//        }

        alignmentService.addAlignmentForOkr(alignmentForOkrList, okr.getId());
            // 根据对齐的okr，设置kr的进度
    }



    @Override
    public void add(Okr okr) {
        OkrStaff login = GetStaffRequestUtil.getStaff();
        log.info("{}新增了名为：{}的okr",login.getName(), okr.getName());
        okr.setProgress(0);
        List<Okr> krList = okr.getSubOkrList();
        OkrStaff creatStaff = GetStaffRequestUtil.getStaff();
        Long creatStaffId = creatStaff.getId();
        okr.setCreatStaffId(creatStaffId);

        super.add(okr);
        List<OkrStaff> staffList = okr.getStaffList();
        if (krList.size() > 0){
            for (Okr okrTmp : krList) {
                okrTmp.setProgress(0);
                okrTmp.setType(okr.getType());
                okrTmp.setCycleId(okr.getCycleId());
                okrTmp.setParentId(okr.getId());
                okrTmp.setCreatStaffId(creatStaffId);
                okrTmp.setLeader(okr.getLeader());
                okrMapper.add(okrTmp);
            }
        }
        // 判断有没有负责人
        if (okr.getLeader() != null){
            // 查看是否存在参与人员
            if (staffList.size() > 0){
                Optional<OkrStaff> first = staffList.stream().filter(e -> e.getId() == okr.getLeader()).findFirst();
                if (!first.isPresent()){
                    Okrandstaff okrandstaff = new Okrandstaff();
                    okrandstaff.setOkrId(Math.toIntExact(okr.getId()));
                    okrandstaff.setCreatId(Math.toIntExact(creatStaffId));
                    okrandstaff.setStaffId(Math.toIntExact(okr.getLeader()));
                    okrandstaff.setCycleId(Math.toIntExact(okr.getCycleId()));
                    okrandstaffMapper.add(okrandstaff);
                }
            } else {
                Okrandstaff okrandstaff = new Okrandstaff();
                okrandstaff.setOkrId(Math.toIntExact(okr.getId()));
                okrandstaff.setCreatId(Math.toIntExact(creatStaffId));
                okrandstaff.setStaffId(Math.toIntExact(okr.getLeader()));
                okrandstaff.setCycleId(Math.toIntExact(okr.getCycleId()));
                okrandstaffMapper.add(okrandstaff);
            }
        }
        // 新增参与人员
        if (staffList.size() > 0){
            for (OkrStaff staff : staffList) {
                Okrandstaff okrandstaff = new Okrandstaff();
                okrandstaff.setStaffId(Math.toIntExact(staff.getId()));
                okrandstaff.setOkrId(Math.toIntExact(okr.getId()));
                okrandstaff.setCreatId(Math.toIntExact(creatStaffId));
                okrandstaff.setCycleId(Math.toIntExact(okr.getCycleId()));
                okrandstaffMapper.add(okrandstaff);
            }
        }
        // 新增对齐目标
        List<Okr> okrList = okr.getAlignmentForOkrList();
        // 存在
        if (okrList != null && okrList.size() > 0){
            alignmentService.addAlignmentForOkr(okrList, okr.getId());
        }

    }

    /**
     * 根据当前登录人来获取okr
     * @return
     */
    @Override
    public List<Okr> getOkrByStaffId(Long cycleId) {

        OkrStaff staff = GetStaffRequestUtil.getStaff();
        Long staffId = staff.getId();

        List<Okr> okrList  = null;
        // 查看是否有okr
        List<Long> okrandstaffsIds = okrandstaffMapper.findByStaffIdAndCycleId(staffId, cycleId);
        // 有
        if (okrandstaffsIds.size() > 0){
            Integer[] okrIds = okrandstaffsIds.stream().distinct().map(Long::intValue).toArray(Integer[]::new);
            // 获取到所有的okr
            okrList = okrMapper.findByIds(okrIds);
            if (okrList.size() > 0){
                for (Okr okr : okrList) {
                    // 获取对齐数据
                    List<Alignment> alignmentList = alignmentMapper.findBySourceId(okr.getId());
                    if (alignmentList.size() > 0){
                        okr.setAlignmentList(alignmentList);
                    }
                    // 获取被对齐数据
                    List<Alignment> alignments = alignmentMapper.findByTargetIdOrParentId(okr.getId());
                    if (alignments.size() > 0){
                        okr.setAlignments(alignments);
                    }
                    // 获取参与人员
                    List<OkrStaff> staffList =  okrandstaffMapper.findStaffIdsByOkrId(okr.getId());
                    okr.setStaffList(staffList);
                    Long leader = okr.getLeader();
                    // 获取负责人
                    if (leader != null){
                        OkrStaff one = staffMapper.findOne(leader);
                        okr.setOkrLeader(one);
                    }
                }
            }
        }
        return okrList;
    }

    /**
     * 通过员工id获取他的okr按周期分类
     * @param staffId
     * @return
     */
    @Override
    public Map<Long, List<Okr>> getOkrByStaffIdGroupByCycle(Long staffId) {

        Map<Long, List<Okr>> groupedByCycleId = null;
        // 查看是否有okr
        List<Okrandstaff> okrandstaffs = okrandstaffMapper.findByStaffId(staffId);
        // 有
        if (okrandstaffs.size() > 0){
            Integer[] okrIds = okrandstaffs.stream().map(Okrandstaff::getOkrId).toArray(Integer[]::new);
            // 获取到所有的okr
            List<Okr> okrList = okrMapper.findByIds(okrIds);
            // 获取到okr下面的参与人员
            for (Okr okr : okrList) {
                // 获取对齐数据
                List<Alignment> alignmentList = alignmentMapper.findBySourceId(okr.getId());
                if (alignmentList.size() > 0){
                    okr.setAlignmentList(alignmentList);
                }
                // 获取被对齐数据
                List<Alignment> alignments = alignmentMapper.findByTargetIdOrParentId(okr.getId());
                if (alignments.size() > 0){
                    okr.setAlignments(alignments);
                }
                // 获取参与人员
                List<OkrStaff> staffList =  okrandstaffMapper.findStaffIdsByOkrId(okr.getId());
                okr.setStaffList(staffList);
                Long leader = okr.getLeader();
                // 获取负责人
                if (leader != null){
                    OkrStaff one = staffMapper.findOne(leader);
                    okr.setOkrLeader(one);
                }
            }
            // 安装周期id，分类
            groupedByCycleId = okrList.stream().collect(Collectors.groupingBy(Okr::getCycleId));
        }

        return groupedByCycleId;
    }

    @Override
    public Okr getOkrDetailById(Long id) {
        Okr okr = super.findOne(id);
        List<Okr> krList = okrMapper.findByParentId(id);
        List<Renew> renewList =  renewMapper.getRenewListByParentId(id);
        okr.setSubOkrList(krList);
        okr.setRenewList(renewList);
        String leaderName = staffMapper.findNameById(okr.getLeader());
        okr.setLeaderName(leaderName);
        Cycle cycle = cycleMapper.findOne(okr.getCycleId());
        okr.setCycle(cycle);
        return okr;
    }

    @Override
    public Map<Long, List<Okr>> getOkrBycycleId() {
        List<Okr> all = okrMapper.findAll();
        Map<Long, Okr> okrMap = all.stream().collect(Collectors.toMap(Okr::getId, e -> e));

        List<Okr> arrayList = new ArrayList<>();

        for (Okr okr : all) {
            if(okr.getParentId() == null){
                arrayList.add(okr);
            } else {
                Okr parent = okrMap.get(okr.getParentId());
                if (parent == null){
                    log.error("获取主okr错误：{}", okr.getId());
                } else {
                    parent.getSubOkrList().add(okr);
                }
            }
        }
        Map<Long, List<Okr>> resultData = arrayList.stream()
                .collect(Collectors.groupingBy(Okr::getCycleId));
        return resultData;
    }

    /**
     * 更改任务
     * @param okr
     */
    @Override
    public void updateProgress(Okr okr) {
        OkrStaff login = GetStaffRequestUtil.getStaff();
        log.info("{}更新：{}，的进度，{}",login.getName(), okr.getName(),okr.getParentProgress());
        okrMapper.updateProgress(okr);
        Okr parent = okrMapper.findParent(okr.getParentId());
        parent.setProgress(okr.getParentProgress());
        okrMapper.updateProgress(parent);
    }

    /**
     * 查看子任务okr详情
     * @param id
     * @return
     */
    @Override
    public Okr getKrDetailById(Long id) {
        Okr okr = super.findOne(id);
        List<Task> taskList = taskMapper.findByKrId(id);
        if (taskList.size() > 0){
            okr.setTaskList(taskList);
        }
        List<Renew> renewList = renewMapper.findByOkrId(id);
        if (renewList.size() > 0){
            okr.setRenewList(renewList);
        }
        return okr;
    }

    /**
     * 查询自己负责的okr
     * @param leaderId
     * @return
     */
    @Override
    public List<Okr> findOkrByLeader(Long leaderId) {

        List<Okr> okrList = okrMapper.findOkrByLeader(leaderId);

        for (Okr okr : okrList) {
            // 获取对齐数据
            List<Alignment> alignmentList = alignmentMapper.findBySourceId(okr.getId());
            if (alignmentList.size() > 0){
                okr.setAlignmentList(alignmentList);
            }
            // 获取被对齐数据
            List<Alignment> alignments = alignmentMapper.findByTargetIdOrParentId(okr.getId());
            if (alignments.size() > 0){
                okr.setAlignments(alignments);
            }
            // 获取参与人员
            List<OkrStaff> staffList =  okrandstaffMapper.findStaffIdsByOkrId(okr.getId());
            okr.setStaffList(staffList);
            Long leader = okr.getLeader();
            // 获取负责人
            if (leader != null){
                OkrStaff one = staffMapper.findOne(leader);
                okr.setOkrLeader(one);
            }
        }

        return okrList;
    }

    @Override
    public void del(Long id) {
        OkrStaff login = GetStaffRequestUtil.getStaff();
        Okr okr = okrMapper.findOne(id);
        // 删除子任务KR
        okrMapper.delByParentId(id);
        // 删除对齐
        alignmentMapper.delBySourceId(id);
        // 删除被对齐
        alignmentMapper.delByTargetIdAndParentId(id);
        // 删除员工和okr的关联
        okrandstaffMapper.delByOkrId(id);
        // 删除评论和记录
        renewMapper.delByParentId(id);
        log.info("{}删除okr名为：{}",login.getName(), okr.getName());
        super.del(id);
    }
}
